<!DOCTYPE html>
<html lang="en">
<head>
    <!--
    ==========================================================================================================

           db         88  88                       8b           d8                         88
          d88b        88  ""                       `8b         d8'                         88    ,d
         d8'`8b       88                            `8b       d8'                          88    88
        d8'  `8b      88  88  ,adPPYYba,  ,adPPYba,  `8b     d8'  ,adPPYYba,  88       88  88  MM88MMM
       d8YaaaaY8b     88  88  ""     `Y8  I8[    ""   `8b   d8'   ""     `Y8  88       88  88    88
      d8""""""""8b    88  88  ,adPPPPP88   `"Y8ba,     `8b d8'    ,adPPPPP88  88       88  88    88
     d8'        `8b   88  88  88,    ,88  aa    ]8I     `888'     88,    ,88  "8a,   ,a88  88    88,
    d8'          `8b  88  88  `"8bbdP"Y8  `"YbbdP"'      `8'      `"8bbdP"Y8   `"YbbdP'Y8  88    "Y888

    ==========================================================================================================

    AliasVault - Privacy-first password manager with built-in email aliasing. Fully encrypted and self-hostable.
    Build (UTC): @BuildVersion

    Source code: https://github.com/aliasvault/aliasvault
    License: AGPLv3
    -->
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"/>
    <title>AliasVault</title>
    <base href="/" />
    <link rel="stylesheet" href="css/app.css?v=@CacheBuster" />
    <link rel="icon" type="image/png" href="favicon.png" />
    <link href="css/tailwind.css?v=@CacheBuster" rel="stylesheet">
    <link rel="manifest" href="manifest.json" />
    <link rel="apple-touch-icon" sizes="500x500" href="img/icon-500.png" />
    <link rel="apple-touch-icon" sizes="192x192" href="img/icon-192.png" />
</head>

<body class="bg-gray-100 dark:bg-gray-900" av-disable="true">
    <div id="loading-screen">
        <div class="fixed inset-0 flex items-center justify-center px-6 pt-8 pb-8">
            <div class="w-full max-w-md space-y-4">
                <div class="p-6 sm:p-8 bg-white rounded-lg shadow dark:bg-gray-800">
                    <div class="text-center">
                        <div class="inner">
                            <div class="index-aliasvault-inline-spinner mx-auto">
                                <div class="index-cloud-shape-inline">
                                    <div class="index-dot-inline index-delay-1"></div>
                                    <div class="index-dot-inline index-delay-2"></div>
                                    <div class="index-dot-inline index-delay-3"></div>
                                    <div class="index-dot-inline index-delay-4"></div>
                                </div>
                            </div>
                            <h2 id="loading-title" class="mt-4 text-xl font-semibold text-gray-900 dark:text-white">AliasVault is loading</h2>
                            <p id="loading-message" class="mt-2 text-sm text-gray-500 dark:text-gray-400">
                                Initializing secure environment. AliasVault prioritizes your privacy by running entirely in your browser. The first load might take a short while.
                            </p>
                            <div class="loading-progress-text text-sm font-medium text-gray-700 dark:text-gray-300 mt-4"></div>
                            <div class="mt-4 text-center">
                                <p id="security-quote" class="text-sm text-primary-600 italic"></p>
                            </div>
                            <div id="error-message" class="hidden text-red-600 dark:text-red-400 mt-4"></div>
                        </div>
                    </div>

                    <style>
                    .index-aliasvault-inline-spinner {
                        height: 51px;
                        width: 112px;
                        display: flex;
                        justify-content: center;
                        align-items: center;
                    }

                    .index-cloud-shape-inline {
                        border: 6px solid #eabf69;
                        border-radius: 9999px;
                        padding: 13px 26px;
                        display: flex;
                        gap: 10px;
                        align-items: center;
                        background-color: transparent;
                        box-shadow: 0 0 4px 2px rgba(0, 0, 0, 0.1);
                    }

                    .index-dot-inline {
                        width: 10px;
                        height: 10px;
                        border-radius: 9999px;
                        background-color: #eabf69;
                        animation: index-pulse-inverted 1.4s infinite ease-in-out;
                    }

                    .index-delay-1 { animation-delay: 0s; }
                    .index-delay-2 { animation-delay: 0.2s; }
                    .index-delay-3 { animation-delay: 0.4s; }
                    .index-delay-4 { animation-delay: 0.6s; }

                    @keyframes index-pulse-inverted {
                        0%, 100% { opacity: 0.3; transform: scale(1); }
                        50% { opacity: 1; transform: scale(1.3); }
                    }
                    </style>
                </div>

                <div id="refresh-button" class="text-center w-full mt-4 p-6 sm:p-8 bg-white rounded-lg shadow dark:bg-gray-800 hidden">
                    <p id="refresh-text" class="text-sm text-gray-600 dark:text-gray-400 mb-2">If loading seems stuck, you can click the button below to refresh the page.</p>
                    <a href="javascript:window.location.reload(true)" class="inline-block px-4 py-2 bg-primary-600 text-white text-sm font-medium rounded-md hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 transition duration-150 ease-in-out">
                        <span id="refresh-button-text">Refresh Page</span>
                    </a>
                </div>
            </div>
        </div>
    </div>

    <div id="app">
    </div>

    <div id="blazor-error-ui" class="text-white bg-red-700 dark:bg-red-900 p-6 border-t-2 border-red-500 dark:border-red-800">
        <div class="container mx-auto max-w-screen-xl px-4">
            <div class="flex flex-col sm:flex-row items-center justify-between gap-4">
                <div class="flex items-center">
                    <svg class="w-8 h-8 text-white mr-4 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
                    </svg>
                    <span id="unhandled-error-text">An unhandled error has occurred. Please try reloading the page. If the issue persists, please contact support.</span>
                </div>
                <div class="flex items-center gap-4">
                    <a href="" class="reload flex items-center px-4 py-2 bg-red-600 hover:bg-red-700 rounded-md transition-colors duration-150">
                        <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/>
                        </svg>
                        <span id="reload-page-text">Reload Page</span>
                    </a>
                    <a class="dismiss hover:text-red-200">
                        <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
                        </svg>
                    </a>
                </div>
            </div>
        </div>
    </div>

    <script>
        // Pre-loading localization system with JSON loading
        let translations = {};

        function getCurrentLanguage() {
            return localStorage.getItem('blazorCulture') ||
                   localStorage.getItem('AppLanguage') ||
                   (navigator.language.split('-')[0] === 'nl' ? 'nl' : 'en');
        }

        async function loadTranslations() {
            const lang = getCurrentLanguage();
            try {
                const response = await fetch(`/locales/${lang}.json`);
                if (response.ok) {
                    translations = await response.json();
                } else {
                    // Fallback to English if the language file is not found
                    const fallbackResponse = await fetch('/locales/en.json');
                    translations = await fallbackResponse.json();
                }
            } catch (error) {
                console.warn('Failed to load localization files, using fallback strings:', error);
                // Fallback translations
                translations = {
                    loading: {
                        title: 'AliasVault is loading',
                        message: 'Initializing secure environment. AliasVault prioritizes your privacy by running entirely in your browser. The first load might take a short while.',
                        refreshText: 'If loading seems stuck, you can click the button below to refresh the page.',
                        refreshButtonText: 'Refresh Page'
                    },
                    errors: {
                        unhandledError: 'An unhandled error has occurred. Please try reloading the page. If the issue persists, please contact support.',
                        webAssemblyError: 'AliasVault requires WebAssembly, which this browser does not support. Try using a more modern browser that supports WebAssembly.',
                        reloadPageText: 'Reload Page'
                    },
                    quotes: {
                        security: [
                            "Your identity is your most valuable asset. Protect it like one.",
                            "In the digital world, a strong password is your first line of defense.",
                            "Security is not a product, but a process."
                        ]
                    }
                };
            }
        }

        function getTranslation(path) {
            const keys = path.split('.');
            let value = translations;
            for (const key of keys) {
                value = value?.[key];
                if (!value) break;
            }
            return value || '';
        }

        function localizeContent() {
            // Localize main loading screen
            const loadingTitle = document.getElementById('loading-title');
            const loadingMessage = document.getElementById('loading-message');
            if (loadingTitle) {
                loadingTitle.textContent = getTranslation('loading.title');
            }
            if (loadingMessage) {
                loadingMessage.textContent = getTranslation('loading.message');
            }

            // Localize refresh button section
            const refreshText = document.getElementById('refresh-text');
            const refreshButtonText = document.getElementById('refresh-button-text');
            if (refreshText) {
                refreshText.textContent = getTranslation('loading.refreshText');
            }
            if (refreshButtonText) {
                refreshButtonText.textContent = getTranslation('loading.refreshButtonText');
            }

            // Localize error section
            const unhandledErrorText = document.getElementById('unhandled-error-text');
            const reloadPageText = document.getElementById('reload-page-text');
            if (unhandledErrorText) {
                unhandledErrorText.textContent = getTranslation('errors.unhandledError');
            }
            if (reloadPageText) {
                reloadPageText.textContent = getTranslation('errors.reloadPageText');
            }

            // Set random security quote
            const securityQuotes = getTranslation('quotes.security');
            if (securityQuotes && securityQuotes.length > 0) {
                const quoteElement = document.getElementById('security-quote');
                const randomIndex = Math.floor(Math.random() * securityQuotes.length);
                if (quoteElement) {
                    quoteElement.textContent = `"${securityQuotes[randomIndex]}"`;
                }
            }
        }

        // Initialize localization
        async function initializeLocalization() {
            await loadTranslations();
            localizeContent();
        }

        // Apply localization immediately
        document.addEventListener('DOMContentLoaded', initializeLocalization);
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', initializeLocalization);
        } else {
            initializeLocalization();
        }

        function manageLoadingScreen() {
            const startTime = new Date().getTime();
            const minDisplayTime = 1000;
            const checkInterval = 500;
            const refreshButtonTimeout = 300000;

            const appElement = document.getElementById('app');
            const refreshButton = document.getElementById('refresh-button');

            appElement.style.visibility = 'hidden';
            loadingScreen.style.display = 'flex';

            // Show refresh button after 30 seconds
            setTimeout(() => {
                refreshButton.classList.remove('hidden');
            }, refreshButtonTimeout);

            // Add click event listener to refresh button
            refreshButton.addEventListener('click', () => {
                window.location.reload();
            });

            const checkContentAndTime = () => {
                const elapsedTime = new Date().getTime() - startTime;
                const hasContent = appElement.innerHTML.trim() !== '';

                if (elapsedTime >= minDisplayTime && hasContent) {
                    loadingScreen.style.display = 'none';
                    appElement.style.removeProperty('visibility');
                    clearInterval(intervalId);
                } else if (elapsedTime % 1000 < checkInterval) {
                    if (!('WebAssembly' in window)) {
                        showError(getTranslation('errors.webAssemblyError'));
                        clearInterval(intervalId);
                    }
                }
            };

            const intervalId = setInterval(checkContentAndTime, checkInterval);
        }

        const loadingScreen = document.getElementById('loading-screen');
        const errorMessageElement = document.getElementById('error-message');

        const showError = (message) => {
            errorMessageElement.textContent = message;
            errorMessageElement.classList.remove('hidden');
            document.querySelector('.loading-progress-text').classList.add('hidden');
            document.querySelector('svg.animate-spin').classList.add('hidden');
        };

        // Listen for unhandled errors
        window.addEventListener('error', function(event) {
            if (event.error && event.error.message && event.error.message.includes('WebAssembly')) {
                showError(getTranslation('errors.webAssemblyError'));
            }
        });

        // Listen for unhandled promise rejections
        window.addEventListener('unhandledrejection', function(event) {
            if (event.reason && event.reason.message && event.reason.message.includes('WebAssembly')) {
                showError(getTranslation('errors.webAssemblyError'));
            }
        });

        window.addEventListener('load', manageLoadingScreen);
    </script>

    <script>
        window.blazorCulture = {
            get: function() {
                return localStorage.getItem('blazorCulture') ||
                       localStorage.getItem('AppLanguage') ||
                       (navigator.language.split('-')[0] === 'nl' ? 'nl' : 'en');
            },
            set: function(culture) {
                localStorage.setItem('blazorCulture', culture);
            }
        };
    </script>

    <script src="js/crypto.js?v=@CacheBuster" async></script>
    <script src="js/utilities.js?v=@CacheBuster" async></script>
    <script src="_framework/blazor.webassembly.js?v=@CacheBuster" async></script>
    <script src="lib/qrcode.min.js?v=@CacheBuster" defer></script>
    <script>
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('service-worker.js');
        }
    </script>
</body>

</html>
